/*****************************************************************************
 * plum_vfs.h
 *
 * Copyright (C) 2020 Jeasonvor <1101627719@qq.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 ****************************************************************************/

#ifndef __PLUM_VFS_H__
#define __PLUM_VFS_H__

/*****************************************************************************
 * Included Files
 ****************************************************************************/

/*****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

/* File open flags */
#define VFS_O_RDONLY 0x0001
#define VFS_O_WRONLY 0x0002
#define VFS_O_RDWR   0x0003
#define VFS_O_CREATE 0x0100
#define VFS_O_EXCL   0x0200
#define VFS_O_TRUNC  0x0400
#define VFS_O_APPEND 0x0800

/* file seek */
#define VFS_SEEK_SET 0
#define VFS_SEEK_CUR 1
#define VFS_SEEK_END 2

/* file type */
#define VFS_TYPE_UNK  0
#define VFS_TYPE_FILE 1
#define VFS_TYPE_DIR  2

#define VFS_HANDLE_MAX 8

#define VFS_CACHE_SIZE 256

/*****************************************************************************
 * Public Types
 ****************************************************************************/

/**文件偏移*/
typedef enum {
    PLUM_VFS_SEEK_SET,
    PLUM_VFS_SEEK_CUR,
    PLUM_VFS_SEEK_END,
} plum_vfs_seek_whence_t;

typedef struct {
    /** flash 读数据操作接口 */
    plum_s32 (*flash_read)(plum_u32 addr, plum_u8 *rData, plum_u32 size);
    /** flash 写数据操作接口 */
    plum_s32 (*flash_write)(plum_u32 addr, plum_u8 *wData, plum_u32 size);

    /** flash 擦除数据接口 */
    plum_s32 (*flash_erase)(plum_u32 addr, plum_u32 size);

    /** flash 起始地址 */
    plum_u32 flash_start_addr;

    /** flash 读数据块大小*/
    plum_u32 flash_read_size;

    /** flash 最小写入大小 */
    plum_u32 flash_prog_size;

    /** flash 块大小 */
    plum_u32 flash_block_size;

    /** flash 块数量*/
    plum_u32 flash_block_count;
} fs_flash_t;

/*****************************************************************************
 * Public Data
 ****************************************************************************/

/*
 * @brief:	挂载文件系统
 *
 * @param[in]:	path	- 	vfs mount point directory name
 * @param[in]:	flash 	-	physical IC handle pointer
 *
 * @retval:	return an error code
 **/
plum_s32 plum_cal_vfs_mount(PLUM_CONST plum_s8 *path, fs_flash_t *flash);

/*
 * @brief:	取消挂载
 *
 * @param[in]	path -   vfs mount point directory name
 *
 * @retval:	return an error code
 **/
plum_s32 vfs_unmount(PLUM_CONST plum_s8 *path);

/**
 * @brief:  打开文件
 *
 * @param[in]:   path       -   文件路径
 * @param[in]:   mode       -   打开模式
 *
 * @return: 成功    -   返回文件描述符
 *          失败    -   返回错误码
 **/
plum_s32 plum_cal_vfs_open(plum_s8 *path, plum_u32 mode);

/**
 * @brief:  关闭文件
 *
 * @param[in]:  fd      -   文件描述符
 *
 * @return: 返回错误码
 **/
plum_s32 plum_cal_vfs_close(plum_u32 fd);

/**
 * @brief:  读取文件
 *
 * @param[in]:  fd      -   文件描述符
 * @param[out]: rData   -   数据输出指针
 * @param[in]:  size    -   读取文件长度
 *
 * @return: 成功    -   返回读取到的数据长度
 *          失败    -   返回错误码
 **/
plum_s32 plum_cal_vfs_read(plum_u32 fd, plum_u8 *rData, plum_u32 size);

/**
 * @brief:  写数据
 *
 * @param[in]:  fd      -   文件描述符
 * @param[in]:  wData   -   待写数据指针
 * @param[in]:  size    -   待写数据长度
 *
 * @return: 成功    -   返回写入的数据长度
 *          失败    -   返回错误码
 */
plum_s32 plum_cal_vfs_write(plum_u32 fd, plum_u8 *wData, plum_u32 size);

/**
 * @brief:  对文件进行偏移
 *
 * @param:  fd      -   文件描述符
 * @param:  offset  -   偏移量
 * @param： whence  -   参考位置
 *
 * @return: 返回错误码
 **/
plum_s32 plum_cal_vfs_seek(plum_u32 fd, plum_u32 offset,
                           plum_vfs_seek_whence_t whence);

/**
 * @brief： 获取文件当前偏移量
 *
 * @param:  fd      -   文件描述符
 *
 * @return：    成功    -   返回当前偏移量
 *              失败    -   返回错误码
 **/
plum_s32 plum_cal_vfs_offset(plum_u32 fd);

/**
 * @brief:  同步写数据
 *
 * @param:  fd      -   文件描述符
 *
 * @return: 返回执行状态
 **/
plum_s32 plum_cal_vfs_sync(plum_u32 fd);

plum_s32 plum_cal_vfs_readdir(PLUM_CONST plum_s8 *path);

/****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
 * Public Function Prototypes
 ****************************************************************************/

/****************************************************************************/
#ifdef __cplusplus
}
#endif
/****************************************************************************/
#endif /* __PLUM_VFS_H__ */
/****************************************************************************/

/****************************************************************************/
/*                                                                          */
/*  End of file.                                                            */
/*                                                                          */
/****************************************************************************/
